package pers.cz.orm.dao;

import pers.cz.common.annotation.TimeLag;
import pers.cz.common.connect.Connection;
import pers.cz.common.connect.IConnection;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @program: jef-orm
 * @description: 默认的sql执行器，特殊点在于每执行一次select、update、delete、insert都要开启一次statement,用完之后立即关闭
 * @author: Cheng Zhi
 * @create: 2023-08-10 13:38
 **/
public class DefaultSqlEngine extends BaseSqlEngine {

    DefaultSqlEngine(IConnection iConnection) {

        super(iConnection);
    }

    @Override
    public <T> T singleExecuteQuery(String sql, Class<T> resultType) {

        return (T) executeQuery(sql, resultType, null).get(0);
    }

    @Override
    @TimeLag
    public <T> List<T> executeQuery(String sql, Class<T> resultType, Map<Integer, Object> params) {
        ResultSet resultSet = null;

        try(PreparedStatement preparedStatement = connection.prepareStatement(sql);) {

            if (params == null || params.isEmpty()) {
                resultSet = preparedStatement.executeQuery();
            } else {
                for (Integer index : params.keySet()) {
                    preparedStatement.setObject(index, params.get(index));
                }
                resultSet = preparedStatement.executeQuery();
            }
            return dealResultSet(resultSet, resultType);
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return new ArrayList<T>();
    }


    @Override
    public int execute(String sql, Map<Integer, Object> params) {

        try(PreparedStatement preparedStatement = connection.prepareStatement(sql);) {
            if (params == null || params.isEmpty()) {
                int count = preparedStatement.executeUpdate();
                return count;
            }

            for (Integer index : params.keySet()) {
                preparedStatement.setObject(index, params.get(index));
            }
            preparedStatement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    @Override
    public void batch(String sql, List<Map<Integer, Object>> lists) {

        try(PreparedStatement preparedStatement = connection.prepareStatement(sql);) {
            int count = 0;
            for (Map<Integer, Object> map : lists) {
                for (Integer index : map.keySet()) {
                    preparedStatement.setObject(index, map.get(index));
                }
                count ++;
                preparedStatement.addBatch();
                if (count == 50) {
                    preparedStatement.executeBatch();
                    preparedStatement.clearBatch();
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

}
